##
# server_process.py - Created by Timothy Morey on 5/31/2012
#
# This file provides an interface to an nvn-server process.
#

import ctypes

from libnvn import client
from libnvn import data_schema
from libnvn import data_source
from libnvn import messages

class ServerProcess:
    ''' Represents an instance of the nvn-server process.

    This object helps communicate with an nvn-server process running on a
    remote machine.
    '''

    def __init__(self, addr, port):
        self.Address = addr
        self.Port = port

        self.RequestLen = 4096
        self.RequestBuffer = ctypes.create_string_buffer(self.RequestLen)

        self.ResponseLen = 4096
        self.ResponseBuffer = ctypes.create_string_buffer(self.ResponseLen)


    def GetDataGridSchema(self, datasource):
        retval = None

        reqlen = ctypes.c_int(self.RequestLen)
        resplen = ctypes.c_int(self.ResponseLen)
        messages.CreateQueryDataGridSchemaRequest(datasource.GetDatasetName(), 
                                                  datasource.Varname, 
                                                  self.RequestBuffer, ctypes.byref(reqlen))
        self.SendRequest(self.RequestBuffer, reqlen, self.ResponseBuffer, resplen)
        retval = data_schema.DataGridSchema()
        messages.ParseQueryDataGridSchemaResponse(self.ResponseBuffer, resplen, ctypes.byref(retval))

        return retval


    def GetDataSetSchema(self, dataset):
        retval = None

        reqlen = ctypes.c_int(self.RequestLen)
        resplen = ctypes.c_int(self.ResponseLen)
        messages.CreateQueryDataSetSchemaRequest(dataset, self.RequestBuffer, ctypes.byref(reqlen))
        self.SendRequest(self.RequestBuffer, reqlen, self.ResponseBuffer, resplen)
        retval = data_schema.DataSetSchema()
        messages.ParseQueryDataSetSchemaResponse(self.ResponseBuffer, resplen, ctypes.byref(retval))

        return retval


    def StartStream(self, port, dataset, varname):
        reqlen = ctypes.c_int(self.RequestLen)
        resplen = ctypes.c_int(self.ResponseLen)
        messages.CreateStartStreamRequest(port, dataset, varname, 
                                          self.RequestBuffer, ctypes.byref(reqlen))
        self.SendRequest(self.RequestBuffer, reqlen, self.ResponseBuffer, resplen);


    def SendRequest(self, req, reqlen, resp, resplen):
        c = ctypes.pointer(client.Client())
        client.ConnectClient(self.Address, self.Port, ctypes.byref(c))
        if bool(c):
            client.SendAndReceive(c, req, reqlen, resp, ctypes.byref(resplen))
            client.DestroyClient(c)



